package com.fulizhe.catlocal.integration.httpclient.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.dianping.cat.Cat;
import com.dianping.cat.local.integration.servlet.CatMsgConstants;
import com.dianping.cat.local.integration.servlet.CatMsgContext;

@RestController
public class HelloController {

	@Autowired
	private ServerProperties sp;

	@GetMapping("/hello")
	public String index(HttpServletRequest request) {
		LoggerFactory.getLogger(this.getClass()).info("开始Apache HttpClient调用....");

		httpTest();

		return String.format(
				"<br><br> 当前请求的TraceId为 [ <strong> <a target=\"_blank\" href=\"./cat/cat.html?traceId=%s\">%s</a> </strong> ] <--- 点击左侧链接跳转到'CAT-LOCAL链路查询页面'查看链路日志 <br><br><br> %s", //
				Cat.getCurrentMessageId(), Cat.getCurrentMessageId(),
				"查看traceId来源, 请打开F12, 然后刷新页面, 在返回HTTP Header中有一个名为X-ROOT-TRACE-ID的key");
	}

	@GetMapping("/calledRemoteService")
	public String index2(HttpServletRequest request) {
		Cat.getManager().setTraceMode(true);
		
		LoggerFactory.getLogger(this.getClass()).info("被Apache HttpClient Invoke....");
		
		
		return "Invoked By Apache HttpClient";
	}

	String httpTest() {
		final String url = String.format("http://127.0.0.1:%s/calledRemoteService", sp.getPort());

		createMessageTree();

		HttpGet request = new HttpGet(url);
		try (CloseableHttpClient httpClient = getHttpClient();
				CloseableHttpResponse response = httpClient.execute(request)) {

			HttpEntity entity = response.getEntity();
			if (entity != null) {
				// return it as a String
				String result = EntityUtils.toString(entity);
				System.out.println(result);
				return result;
			}

			return "";

		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	CloseableHttpClient getHttpClient() {
		final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		final String rootId = requestAttributes.getAttribute(Cat.Context.ROOT, 0).toString();
		final String childId = requestAttributes.getAttribute(Cat.Context.CHILD, 0).toString();
		final String parentId = requestAttributes.getAttribute(Cat.Context.PARENT, 0).toString();

		CloseableHttpClient httpClient = HttpClients.custom()
				// 设置拦截器
				.addInterceptorFirst(new HttpRequestInterceptor() {

					@Override
					public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
						request.addHeader(Cat.Context.ROOT, rootId);
						request.addHeader(Cat.Context.CHILD, childId);
						request.addHeader(Cat.Context.PARENT, parentId);
						request.addHeader(CatMsgConstants.APPLICATION_KEY, Cat.getManager().getDomain());

					}
				}).build();

		return httpClient;
	}

	/**
	 * 统一设置消息编号的messageId
	 */
	private void createMessageTree() {
		LoggerFactory.getLogger(this.getClass()).debug("统一设置消息编号的messageId");
		final CatMsgContext context = new CatMsgContext();
		Cat.logRemoteCallClient(context);
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		requestAttributes.setAttribute(Cat.Context.PARENT, context.getProperty(Cat.Context.PARENT), 0);
		requestAttributes.setAttribute(Cat.Context.ROOT, context.getProperty(Cat.Context.ROOT), 0);
		requestAttributes.setAttribute(Cat.Context.CHILD, context.getProperty(Cat.Context.CHILD), 0);
		requestAttributes.setAttribute(CatMsgConstants.APPLICATION_KEY, Cat.getManager().getDomain(), 0);
	}

}